package com.freight.order.serviceimpl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.freight.base.entity.Dict;
import com.freight.base.entity.DictData;
import com.freight.base.service.DictDataService;
import com.freight.base.service.DictService;
import com.freight.core.common.constant.CommonConstant;
import com.freight.core.common.exception.FreightException;
import com.freight.core.common.utils.ObjectUtil;
import com.freight.core.common.utils.SecurityUtil;
import com.freight.core.common.vo.SearchVo;
import com.freight.core.entity.User;
import com.freight.core.service.OperationLogService;
import com.freight.order.constant.OrderStatus;
import com.freight.order.dao.GoodsLoadingTimeDao;
import com.freight.order.dao.OrderGoodsDao;
import com.freight.order.dto.OrderGoodsDto;
import com.freight.order.entity.GoodsLoadingTime;
import com.freight.order.entity.OrderGoods;
import com.freight.order.mapper.OrderGoodsVoMapper;
import com.freight.order.mapper.QuotationRecordMapper;
import com.freight.order.service.CompanyOrderGoodsService;
import com.freight.order.vo.QuotationRecordVo;
import com.freight.user.util.UserDtoUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 货物需求接口实现
 *
 * @author huyingtai
 */
@Slf4j
@Service
@Transactional
public class CompanyOrderGoodsServiceImpl implements CompanyOrderGoodsService {

    @Autowired
    private OrderGoodsDao orderGoodsDao;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private GoodsLoadingTimeDao goodsLoadingTimeDao;

    @Autowired
    private QuotationRecordMapper quotationRecordMapper;

    @Autowired
    private DictService dictService;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private OrderGoodsVoMapper orderGoodsVoMapper;

    @Autowired
    private DictDataService dictDataService;

    @Override
    public OrderGoodsDao getRepository() {
        return orderGoodsDao;
    }


    @Override
    public String publis() {

        return null;
    }

    @Override
    public Page<OrderGoods> findByCondition(OrderGoods orderGoods, SearchVo searchVo, Pageable pageable) {
        User u = securityUtil.getCurrUser();
        return orderGoodsDao.findAll(new Specification<OrderGoods>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<OrderGoods> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                List<Predicate> list = new ArrayList<>();
                Path<Date> createTimeField = root.get("createTime");
                Path<Long> id = root.get("id");
                Path<Long> companyUserId = root.get("companyUserId");
                Path<String> beginAreaCode = root.get("beginAreaCode");
                Path<String> endAreaCode = root.get("endAreaCode");

                // 创建时间
                if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                }


                // 货源id
                if (null != orderGoods.getId()) {
                    list.add(cb.equal(id, orderGoods.getId()));
                }

                // 货主只能看到自己的货源  如果角色是 货主的话
                if (!u.getUserType().equals(CommonConstant.USER_TYPE_DRIVER)) {
                    list.add(cb.equal(companyUserId, u.getId()));
                }

                // 起始城市
                if (null != orderGoods.getEndAreaCode()) {
                    list.add(cb.equal(beginAreaCode, orderGoods.getEndAreaCode()));
                }
                // 结束城市
                if (null != orderGoods.getEndAreaCode()) {
                    list.add(cb.equal(endAreaCode, orderGoods.getEndAreaCode()));
                }

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        }, pageable);
    }


    @Override
    public String publicGoods(OrderGoodsDto orderGoodsDto) {
        User u = securityUtil.getCurrUser();

        Dict dict = dictService.findByType("sensitive_thesaurus_examine");
        if (dict != null) {
            List<DictData> lists = dictDataService.findByDictId(dict.getId());
            for (DictData dictData:lists) {
                if (orderGoodsDto.getGoodSubType().indexOf(dictData.getDescription())!=-1){
                    throw new FreightException("货品名称存在敏感词");
                }
                if (orderGoodsDto.getContent().indexOf(dictData.getDescription())!=-1){
                    throw new FreightException("货品备注存在敏感词");
                }
            }
        }

        OrderGoods orderGoods = new OrderGoods();
        ObjectUtil.copyPropertiesIgnoreNull(orderGoodsDto, orderGoods);
        orderGoods.setTotalGoodWeight(orderGoodsDto.getGoodWeight());
        orderGoods.setCompanyUserId(orderGoodsDto.getCompanyUserId());
        String [] loadingTimes = orderGoodsDto.getLoadingTimes().split(",");
        List<GoodsLoadingTime> list = new ArrayList<>();
        if(loadingTimes!=null&&loadingTimes.length>0){
            orderGoods = orderGoodsDao.save(orderGoods);
            for (String loadingTime:loadingTimes) {
                GoodsLoadingTime goodsLoadingTime = new GoodsLoadingTime();
                goodsLoadingTime.setGoodsId(orderGoods.getId());
                goodsLoadingTime.setLoadingTime(loadingTime);
                goodsLoadingTime.setLoadingState("1");
                list.add(goodsLoadingTime);
            }
            goodsLoadingTimeDao.saveAll(list);
        }

        return "发布成功";
    }

    @Override
    public String delGoods(Long goodId) {
        User u = securityUtil.getCurrUser();
        OrderGoods goods = orderGoodsDao.getOne(goodId);

        List<QuotationRecordVo> list=quotationRecordMapper.driverRecord(goodId,null);
        if (list!=null && list.size()>0){
            throw new FreightException("已有报价,不能删除该货物");
        }else {
            goods.setStatus(OrderStatus.GOODS_CANCEL);
            orderGoodsDao.save(goods);
        }
        //操作记录
        operationLogService.saveOperationLog(5,"货源删除",goodId.toString());
        return "删除成功";
    }

    @Override
    public String updateGoodsStatus(Long goodId,Integer status) {
        User u = securityUtil.getCurrUser();
        OrderGoods goods = get(goodId);

        if (goods!=null){
            goods.setStatus(status);
            orderGoodsDao.save(goods);
        }else {
            throw new FreightException("操作错误");
        }
        return "修改成功";
    }

    @Override
    public String delGoodsList(Long[] goodIds) {
        User u = securityUtil.getCurrUser();
        List goodIdList = new ArrayList<Long>();
        if (UserDtoUtils.isAdminOrCompany(u)) {
            for (Long goodId : goodIds) {
                List<QuotationRecordVo> list=quotationRecordMapper.driverRecord(goodId,null);
                if (list!=null && list.size()>0){
                    throw new FreightException("已有报价,不能删除该货物");
                }
            }
            for (Long goodId : goodIds) {
                delGoods(goodId);
            }
        } else {
            throw new FreightException("请先登入或注册为货主");
        }
        return "删除成功";
    }

    @Override
    public List<OrderGoods> getGoodsList(List<Long> goodIds) {
        return orderGoodsDao.getGoodByIds(goodIds);
    }

    @Override
    public String updateGoods(OrderGoodsDto orderGoodsDto, Long goodId) {

        User u = securityUtil.getCurrUser();

        Dict dict = dictService.findByType("sensitive_thesaurus_examine");
        if (dict != null) {
            List<DictData> lists = dictDataService.findByDictId(dict.getId());
            for (DictData dictData:lists) {
                if (orderGoodsDto.getGoodSubType().indexOf(dictData.getDescription())!=-1){
                    throw new FreightException("货品名称存在敏感词");
                }
                if (orderGoodsDto.getContent().indexOf(dictData.getDescription())!=-1){
                    throw new FreightException("货品备注存在敏感词");
                }
            }
        }

        OrderGoods orderGoods = orderGoodsDao.getOne(goodId);
        ObjectUtil.copyPropertiesIgnoreNull(orderGoodsDto, orderGoods);
        orderGoods.setTotalGoodWeight(orderGoodsDto.getGoodWeight());
        orderGoods.setStatus(0);
        String [] loadingTimes = orderGoodsDto.getLoadingTimes().split(",");
        List<GoodsLoadingTime> list = new ArrayList<>();
        if(loadingTimes!=null&&loadingTimes.length>0){
            orderGoods = orderGoodsDao.save(orderGoods);
            List<GoodsLoadingTime> loadingNotList = orderGoodsVoMapper.getNotLoadingTime(orderGoods.getId(), "1");

            for (String loadingTime:loadingTimes) {
                GoodsLoadingTime goodsLoadingTime = new GoodsLoadingTime();
                goodsLoadingTime.setGoodsId(orderGoods.getId());
                goodsLoadingTime.setLoadingTime(loadingTime);
                goodsLoadingTime.setLoadingState("1");
                list.add(goodsLoadingTime);
            }
            goodsLoadingTimeDao.saveAll(list);
            goodsLoadingTimeDao.deleteAll(loadingNotList);
        }

        //操作记录
        operationLogService.saveOperationLog(5,"修改货源信息",goodId.toString());
        return goodId.toString();
    }

}